package com.company.nuwa.mybatis.generator.plugins;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.OutputUtilities;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
 * <p>批量插入</p>
 *
 * @author Lionel Lee
 * @version 1.0: BatchInsertPlugin.java
 * @date 2021/5/3  22:30 星期一
 */
public class BatchReplacePlugin extends PluginAdapter {

    public BatchReplacePlugin() {
        super();
    }

    @Override
    public boolean validate(List<String> paramList) {
        return true;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
        generateBatchInsert(interfaze, introspectedTable);
        return super.clientGenerated(interfaze, introspectedTable);
    }

    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {

        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//数据库表名  

        List<IntrospectedColumn> columns = new ArrayList<IntrospectedColumn>();

        XmlElement parentElement = document.getRootElement();

        XmlElement batchInsertElement = new XmlElement("insert");
        batchInsertElement.addAttribute(new Attribute("id", "batchReplace"));
        batchInsertElement.addAttribute(new Attribute("parameterType", "list"));

        StringBuilder sql = new StringBuilder("replace into " + tableName + "\n");
        OutputUtilities.xmlIndent(sql, 3);
        sql.append("(");
        StringBuilder cols = new StringBuilder();
        StringBuilder vals = new StringBuilder();
        columns = introspectedTable.getAllColumns();

        Iterator<IntrospectedColumn> iterator = columns.iterator();
        int i = 0;
        //OutputUtilities.xmlIndent(cols,3);
        //OutputUtilities.xmlIndent(vals, 3);
        while (iterator.hasNext()) {
            IntrospectedColumn column = iterator.next();
            cols.append(column.getActualColumnName()).append(",");
            vals.append("#{ item." + column.getJavaProperty() + ", jdbcType="
                        + column.getJdbcTypeName() + "}");
            vals.append(",");
            i++;
            if (i == 3) {
                cols.append("\n");
                vals.append("\n");
                OutputUtilities.xmlIndent(cols, 3);
                OutputUtilities.xmlIndent(vals, 3);
                i = 0;
            }

        }
        cols = cols.deleteCharAt(cols.lastIndexOf(","));
        vals = vals.deleteCharAt(vals.lastIndexOf(","));
        sql.append(cols).append(")\n");
        OutputUtilities.xmlIndent(sql, 2);
        sql.append("values \n");
        OutputUtilities.xmlIndent(sql, 2);
        sql.append(
            "<foreach collection=\"list\" item=\"item\" index=\"index\" separator=\",\" > \n");
        OutputUtilities.xmlIndent(sql, 3);
        sql.append("( " + vals + ") \n");

        OutputUtilities.xmlIndent(sql, 2);
        sql.append("</foreach>");

        batchInsertElement.addElement(new TextElement(sql.toString()));

        parentElement.addElement(batchInsertElement);

        return super.sqlMapDocumentGenerated(document, introspectedTable);
    }

    /**
     * 自定义批量插入方法
     * @param interfaze
     * @param introspectedTable
     */
    private void generateBatchInsert(Interface interfaze, IntrospectedTable introspectedTable) {

        Method m = new Method("batchReplace");
        m.setVisibility(JavaVisibility.PUBLIC);
        m.setReturnType(FullyQualifiedJavaType.getIntInstance());
        m.setAbstract(true);
        m.addJavaDocLine("/**");
        m.addJavaDocLine("* 批量插入/更新");
        m.addJavaDocLine("* @param list 记录");
        m.addJavaDocLine("* @return int");
        m.addJavaDocLine(" */");
        m.addAnnotation("@Override");
        String type;
        if (!introspectedTable.getRules().generatePrimaryKeyClass()) {
            type = introspectedTable.getBaseRecordType();
        } else {
            type = introspectedTable.getPrimaryKeyType();
        }
        m.addParameter(new Parameter(new FullyQualifiedJavaType("List<" + type + ">"), "list"));
        context.getCommentGenerator().addGeneralMethodComment(m, introspectedTable);
        interfaze.addImportedType(FullyQualifiedJavaType.getNewListInstance());
        interfaze.addImportedType(new FullyQualifiedJavaType(type));
        interfaze.addMethod(m);
    }

}
